home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC World Interactive 7
/
PC World Interactive 7.iso
/
program
/
cprog.EXE
/
BMP2BGI1.ZIP
/
BMP2BGI2.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-05-25
|
8KB
|
183 lines
//////////////////////////////////////////////////////////////////////////
// ProcessBMP(char *Filename)
// This routine opens the BMP file and displays it pixel by
// pixel. Then, the video image is translated to BGI format.
// Call AccessBMP before using this routine. BMP file
// structures should be defined as global vars in the calling
// routine. After translating, the BGI-formatted image is
// stored in the file w/ a .BGI extension. If the FILE.BGI
// already exists, it is written over.
//////////////////////////////////////////////////////////////////////////
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <graphics.h>
#include <alloc.h>
#include "bmp.h" // BMP file structure
#include "bgi.h" // BGI file structure
// Max size of 10k. Borland's
#define VBUFFSIZE 10240 // default size (4k) is too small for
// practical purposes.
extern BITMAPFILEHEADER BMPHeader; // BMP File header
extern BITMAPINFOHEADER BMPInfo;
extern void StoreBGI(FILE *, int, int, char far *VidBuf[5]);
BGIPREFACE BGIHeader; // BGI File Header
// 16-Color pallete for Microsoft's BMP's
struct palettetype pal = { {MAXCOLORS}, // which is different from Borland's 16-
{ EGA_BLACK, // color pallete, intentionally?
EGA_RED,
EGA_GREEN,
EGA_CYAN,
EGA_BLUE,
EGA_MAGENTA,
EGA_BROWN,
EGA_DARKGRAY,
EGA_LIGHTGRAY,
EGA_LIGHTRED,
EGA_LIGHTGREEN,
EGA_YELLOW,
EGA_LIGHTBLUE,
EGA_LIGHTMAGENTA,
EGA_LIGHTCYAN,
EGA_WHITE
}
};
void ProcessBMP(char *BMPFile, char far *VidBuf[5])
{
FILE *Fn, *Fo; // Fn: BMP file; Fo: BGI file
int gdriver=DETECT,gmode; // vars for graphics mode
int x, y, maxx, maxy; // bookkeeping vars
char Color, buff[80];
Fn = fopen(BMPFile,"rb"); // Open BMP file
strset(buff,NUL); // Create BGI file name as
strtok(BMPFile,"."); // "BMP_File_Name.BGI"
sprintf(buff,"%s.BGI",BMPFile);
Fo = fopen(buff,"wb");
// Jump to image data in
fseek(Fn,BMPHeader.bfOffBits,SEEK_SET); // BMP file
// register a driver that was added into graphics.lib
// & adjust the size
registerfarbgidriver(EGAVGA_driver_far);
setgraphbufsize(VBUFFSIZE);
// check heap space
if ((BMPInfo.biWidth * BMPInfo.biHeight) >= farcoreleft())
{
printf("Coreleft> not enough heap space. %lu bytes were requested\n", (unsigned long) BMPInfo.biWidth * BMPInfo.biHeight);
printf(" There are %lu bytes of available RAM.\n", farcoreleft());
printf(" Try reducing the size of the image.\n");
printf("Coreleft> Press any key to halt.");
getch();
exit(1);
}
// initialize graphics and check status
initgraph(&gdriver, &gmode, "");
x = graphresult();
if (x != grOk) // an error occurred
{
printf("InitGraph> %s\n", grapherrormsg(x));
printf("InitGraph> Press any key to halt.");
getch();
exit(1);
}
// Set the image size based the smaller
// of the video screen or video image
x = getmaxx();
y = getmaxy();
maxx = min(x,BMPInfo.biWidth);
maxy = min(y,BMPInfo.biHeight);
// Set pallette to accomodate
// Microsoft's 16-color pallete
setallpalette(&pal);
// Inform User what's happening
x = 1;
cleardevice();
outtextxy(1,x,"First, the BMP will be displayed...this will take some time.");
x += 7 + textheight("W");
outtextxy(1,x,"Then, the image will be slowly masked...this will also take time.");
x += 27 + textheight("W");
outtextxy(1,x,"* Press Any Key When Ready *");
getch();
cleardevice();
// Full-screen images take a long time,
// so warn the user of this
if (maxx == getmaxx() && maxy == getmaxy()) outtextxy(1,1,"Now would be a good time to make some coffee!");
////////////////////////////////////////////////// The heart of it all
y = maxy;
// Read in & display BMP
// Note: BMP's are stored in
// bottom-up fashion, so we'll
// draw from the bottom to the top
// Also, since the program is setup
// only for 16-Color BMP's, there
// are 4 bits for each pixel
do
{
for (x=0; x < maxx; x++)
{
fread(&Color,sizeof(Color),1,Fn);
putpixel(x++,y,(Color>>4));
putpixel(x,y,(Color&0xf));
}
} while (y-- > 0);
// Set up BGI Header
BGIHeader.PType = 1;
BGIHeader.palette = pal;
BGIHeader.Width = maxx;
BGIHeader.Height = maxy;
// Figure out where in BGI
// file the image data will
// be placed, so that the
// BGI Header can preceed this
fseek(Fo, (long) sizeof(BGIHeader), SEEK_SET);
BGIHeader.Foffset = ftell(Fo);
// Now jump back to start of BGI
// file and write out BGI Header
fseek(Fo, 0L, SEEK_SET);
fwrite(&BGIHeader,sizeof(BGIHeader), 1, Fo);
// Save video image into video buffer
StoreBGI(Fo, BGIHeader.Width, BGIHeader.Height,VidBuf);
y = 0;
// Now erase the image to show
// user that something is happening
do
{
for (x=0; x < maxx; x++) putpixel(x,y,EGA_BLACK);
} while (y++ < maxy);
closegraph();
fclose(Fo);
fclose(Fn);
}